package com.jxl.coreplay.managers
{
	import com.jxl.coreplay.constants.VideoConstants;
	import com.jxl.coreplay.core.IDestroy;
	import com.jxl.coreplay.core.IVideoPlayer;
	import com.jxl.coreplay.events.VideoEvent;
	import com.jxl.coreplay.vo.StreamConfigurationVO;
	
	import flash.events.EventDispatcher;

	[Event(name="videoDurationChanged", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="streamTypeChanged", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="videoStarted", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="metadata", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="videoStopped", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="videoSeeked", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="videoResumed", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="videoPaused", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="videoCompleted", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="videoNotFound", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="bufferFull", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="bufferEmpty", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="liveDelayGood", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="liveDelayOk", type="com.jxl.coreplay.events.VideoEvent")]
	[Event(name="liveDelayBad", type="com.jxl.coreplay.events.VideoEvent")]
	public class CorePlayStreamManager extends EventDispatcher implements IVideoPlayer, IDestroy
	{
		
		public var playing:Boolean = false;
		protected var __impl:IVideoPlayer;
		protected var __videoType:StreamConfigurationVO;
		
		public function CorePlayStreamManager()
		{
			super();
		}
		
		public function initialize(videoType:StreamConfigurationVO):void
		{
			destroy();
			__videoType = videoType;
			switch(videoType.type)
			{
				case VideoConstants.LIVE:
					__impl = new LiveStreamManager(videoType);
					break;
				
				case VideoConstants.STREAMING:
					__impl = new StreamingStreamManager(videoType);
					break;
					
				case VideoConstants.PROGRESSIVE:
					__impl = new ProgressiveStreamManager(videoType);
					break;
			}
			
			
			__impl.addEventListener(VideoEvent.VIDEO_STATE_CHANGED, 		bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.STREAM_TYPE_CHANGED,			bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.METADATA, 					bubbleVideoEvent);
			
			__impl.addEventListener(VideoEvent.VIDEO_STARTED, 				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.VIDEO_STOPPED, 				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.VIDEO_SEEKED,				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.VIDEO_RESUMED, 				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.VIDEO_PAUSED,				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.VIDEO_COMPLETED, 			bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.VIDEO_NOT_FOUND,				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.BUFFER_FULL, 				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.BUFFER_EMPTY, 				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.LIVE_DELAY_GOOD, 			bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.LIVE_DELAY_OK, 				bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.LIVE_DELAY_BAD, 				bubbleVideoEvent);
			
			__impl.addEventListener(VideoEvent.VIDEO_SIZE_CHANGED, 			bubbleVideoEvent);
			__impl.addEventListener(VideoEvent.VIDEO_DURATION_CHANGED,		bubbleVideoEvent);
		}
		
		protected function bubbleVideoEvent(event:VideoEvent):void
		{
			dispatchEvent(event);
		}
		
		
		public function play():void
		{
			if(__impl != null)
			{
				__impl.play();
				playing = true;
			} 
		}
		
		public function pause():void
		{
			if(__impl != null)
			{
				__impl.pause();
				playing = false;
			} 
		}
		
		public function stop():void
		{
			if(__impl != null)
			{
				 __impl.stop();
				 playing = false;
			}
		}
		
		public function seek(offset:Number):void
		{
			if(__impl != null) __impl.seek(offset);
		}
		
		public function resume():void
		{
			if(__impl != null)
			{
				(__impl as AbstractStreamManager).resume();
			}
		}
		
		public function get volume():Number
		{
			if(__impl != null) 
			{
				return __impl.volume;
			} 
			else
			{
				return 0;
			}
		}
		
		public function set volume(val:Number):void
		{
			if(__impl != null) __impl.volume = val;
		}
		
		public function get bufferLength():Number
		{
			if(__impl != null) 
			{
				return __impl.bufferLength;
			} 
			else
			{
				return 0;
			}
		}
		
		public function get bufferTime():Number
		{
			if(__impl != null) 
			{
				return __impl.bufferTime;
			} 
			else
			{
				return 0;
			}
		}
		
		public function get bytesLoaded():Number
		{
			if(__impl != null) 
			{
				return __impl.bytesLoaded;
			} 
			else
			{
				return 0;
			}
		}
		
		public function get bytesTotal():Number
		{
			if(__impl != null) 
			{
				return __impl.bytesTotal;
			} 
			else
			{
				return 0;
			}
		}
		
		public function get duration():Number
		{
			if(__impl != null) 
			{
				return __impl.duration;
			} 
			else
			{
				return 0;
			}
		}
		
		public function get time():Number
		{
			if(__impl != null) 
			{
				return __impl.time;
			} 
			else
			{
				return 0;
			}
		}
		
		public function get currentFPS():Number
		{
			if(__impl != null) 
			{
				return __impl.currentFPS;
			} 
			else
			{
				return 0;
			}
		}
		
		public function get liveDelay():Number
		{
			if(__impl != null) 
			{
				return __impl.liveDelay;
			} 
			else
			{
				return 0;
			}
		}
		
		public function destroy():void
		{
			if(__impl is IDestroy)
			{
				IDestroy(__impl).destroy();
			}
			__impl = null;
			
			__videoType = null;
			
		}
		
	}
}